package com.laboratory.manage.controller;

import cn.hutool.core.io.FileUtil;
import com.laboratory.manage.Exception.BizCodeEnum;
import com.laboratory.manage.entity.MonographEntity;
import com.laboratory.manage.service.MonographService;
import com.laboratory.manage.utils.FileUtils;
import com.laboratory.manage.utils.PageUtils;
import com.laboratory.manage.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/monograph")
public class MonographController {

    @Autowired
    private MonographService monographService;

    //上传
    @PostMapping("/save")
    public R save(@RequestBody MonographEntity monograph){
        return monographService.upLoadMonograph(monograph);
    }

    //修改
    @PostMapping("/updateMonograph")
    public R update(@RequestBody MonographEntity monograph) {
        return monographService.updateMonograph(monograph);
    }

    //删除
    @PostMapping("/removeMonograph")
    public R delete(@RequestBody Long[] ids){
        boolean flag = monographService.deleteByIds(ids);
        if (flag){
            return R.ok();
        }
        return R.error();
    }

    //分页查询
    @GetMapping("/list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = monographService.queryPage(params);

        return R.ok().put("data", page);
    }


    //下载
    @GetMapping("/downMonograph/{monographId}")
    public R downfile(HttpServletResponse response, @PathVariable Long monographId) throws IOException {
        if (monographId == null) {
            return R.error(BizCodeEnum.ID_NOT_EXIST.getCode(), BizCodeEnum.ID_NOT_EXIST.getMsg());
        }
        //根据id查询
        MonographEntity monograp = monographService.getById(monographId);
        String monographPath = monograp.getMonographPath();
        if (monographPath == null){
            //文件不存在 返回错误
            return R.error(BizCodeEnum.MONOGRAPH_NOT_EXIST.getCode(), BizCodeEnum.MONOGRAPH_NOT_EXIST.getMsg());
        }
        File file = new File(monographPath);
        if (!file.exists()){
            //文件不存在 返回错误
            return R.error(BizCodeEnum.MONOGRAPH_NOT_EXIST.getCode(), BizCodeEnum.MONOGRAPH_NOT_EXIST.getMsg());
        }

        String filename = URLEncoder.encode(monograp.getMonographName() + FileUtils.getFileExtension(file), "UTF-8");
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int) file.length());
        response.setHeader("Content-Disposition","attachment;filename="  + new String( filename.getBytes("utf-8"), "ISO8859-1" ) );

        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");

        byte[] bytes = FileUtil.readBytes(file);
        OutputStream os = response.getOutputStream();
        os.write(bytes);
        os.close();
        return R.ok();
    }


    //zip下载
    @GetMapping("/downZIPMonograph/{monographId}")
    public ResponseEntity<?> downloadSingleFileAsZip(@PathVariable Long monographId) throws IOException {
        // 根据id查询
        MonographEntity monograph = monographService.getById(monographId);
        String monographPath = monograph.getMonographPath();
        if (monographPath == null){
            return ResponseEntity.badRequest().body("专著不存在");
        }
        File file = new File(monographPath);
        if (!file.exists()) {
            return ResponseEntity.badRequest().body("文件不存在");
        }

        // 构造附件的文件名，并将其编码为 UTF-8
        String filename = monograph.getMonographName() + FileUtils.getFileExtension(file);
        String encodedFilename = URLEncoder.encode(monograph.getMonographName(), "UTF-8");

        // 设置响应头信息
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment",
                encodedFilename + ".zip");

        // 获取输出流并写入 ZIP 文件
        try (FileInputStream in = new FileInputStream(file)) {
            byte[] buffer = new byte[1024 * 10];
            int len;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            // 将原始文件添加到 ZIP 文件
            try (ZipOutputStream zos = new ZipOutputStream(baos)) {
                ZipEntry zipEntry = new ZipEntry(filename);
                zos.putNextEntry(zipEntry);
                while ((len = in.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
                zos.closeEntry();
            } catch (IOException e) {
                // code 返回500错误 msg: 返回具体错误 e.getMessage()
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("压缩文件失败：" + e.getMessage());
            }

            // 获取 ZIP 文件并将其作为字节数组写入响应的输出流
            byte[] bytes = baos.toByteArray();
            headers.setContentLength(bytes.length);
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("读取文件失败：" + e.getMessage());
        }
    }
}
